﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace Hockey.Shared
{
    /// <summary>
    /// Interface of bond between nodes 
    /// </summary>
    public interface IBond
    {
        bool HasBeenVisited
        { get; }

        ePuckDir? VisitedByPlayer
        { get; }

        INode GetNextNode(INode thisNode);
    }

    /// <summary>
    /// Node interface
    /// </summary>
    public interface INode
    {
        Coordinate Coordinate
        { get; }

        bool IsGate
        { get; }

        bool HasBeenVisited
        { get; }

        IDictionary<eMoveDirection, IBond> Bonds
        { get; }

        bool HasPuck
        { get; }       
    }

    /// <summary>
    /// Board inteface
    /// </summary>
    public interface IBoard: IService
    {
        int Width
        { get; }

        int Height
        { get; }

        ePuckDir PuckDirection
        { get; }


        INode PuckNode
        { get; }

        bool IsMoveCompleted
        { get; }

        void Init(int width, int height, ePuckDir puckDirection = ePuckDir.Up);

        INode Get(Coordinate coor);
        INode Get(int row, int col);
        void Play(eMoveDirection direction, out bool isFinalMove);
        bool CanPlayInThisDirection(eMoveDirection direction);
        bool HasGameFinished();
        ePuckDir? GetWinner();

        bool CanMoveBack();
        bool CanMoveForward();
        void MoveBack();
        void MoveForward();
        void MoveToBeginning();
        void MoveToEnd();

        void NewGame();
        void Load(Stream stream);
        void Save(Stream stream);
    }

    /// <summary>
    /// Board interface for engine
    /// </summary>
    public interface IBoardForEngine: IBoard
    {
        void EnginePlay(eMoveDirection direction, out bool isFinalMove);
        void EnginePlayBack();

    }

    /// <summary>
    /// Event arguments for computed move
    /// </summary>
    public class ComputedMoveEventArgs: EventArgs
    {
        public eMoveDirection[] Move;
    }

    /// <summary>
    /// The interface for engine
    /// </summary>
    public interface IEngine: IService
    {
        event EventHandler<ComputedMoveEventArgs> MoveComputedEvent;
        void StartMoveComputing(eEngineLevel engineLevel);
    }
}
